/*
 * Copyright (c) 2023 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#ifndef DYN_SERVICE_INC_SE_CARD_CHANNEL_INNER_H
#define DYN_SERVICE_INC_SE_CARD_CHANNEL_INNER_H

#include <tee_internal_se_api.h>

#include "dyn_services_card_channel.h"

#ifdef __cplusplus
extern "C" {
#endif

#define MAX_INPUT_COMMAND_LEN 512U

#define MAX_SE_READER_COUNT 8U
#define MAX_SE_READER_NAME_SIZE 64U

#define RES_APDU_MAX_LEN 261
#define RES_APDU_MIN_LEN 2

typedef struct SecureElementContext {
    char readerName[MAX_SE_READER_NAME_SIZE];
    uint8_t aid[AID_LENGTH_MAX];
    uint32_t aidLen;
    TEE_SEServiceHandle service;
    TEE_SEReaderHandle reader;
    TEE_SESessionHandle session;
    TEE_SEChannelHandle channel;
} SecureElementContext;

SecureElementContext *CreateSecureElementContext(const char *readerName, const AppIdentifier *identifier);

void DestroySecureElementContext(SecureElementContext *context);

ResultCode SeChannelOpen(SecureElementContext *context);

ResultCode SeChannelClose(SecureElementContext *context);

ResultCode SeSecureChannelOpen(SecureElementContext *context, const uint8_t *key, uint32_t keyLen, uint8_t keyVersion,
    uint8_t keyId);

ResultCode SeSecureChannelClose(SecureElementContext *context);

ResultCode SeChannelTransmit(SecureElementContext *context, const uint8_t *command, uint32_t commandLen,
    uint8_t *response, uint32_t *responseLen);

ResultCode SeChannelChannelGetOpenResponse(SecureElementContext *context, uint8_t *response, uint32_t *responseLen);

bool IsApduResponseSuccess(const uint8_t *response, uint32_t length);

TEE_SEReaderHandle FindSeReaderByName(TEE_SEServiceHandle service, const char *readerName);

#ifdef __cplusplus
}
#endif

#endif // DYN_SERVICE_INC_SE_CARD_CHANNEL_INNER_H